/* eslint-disable react/display-name */
import { Button, Input, Form, Space, Drawer, Table, Checkbox, CheckboxProps } from "antd";
import React, { useState, useRef, memo, forwardRef, useImperativeHandle, useCallback } from "react";
import { v4 as uuidv4 } from "uuid";
import { Role, RolePermission, roleSave, roleView } from "./roleApi";
import { loadRouterArray } from "@/routers";
import { RouteObject } from "@/routers/interface";
import { genParentMap } from "@/utils/colUtil";
// 新增 or 编辑角色
export default memo(
	forwardRef(function FormDrawer(props: DataUpdate<Role.RoleDTO>, ref: any) {
		const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
		const [open, setOpen] = useState<boolean>(false);
		const [action, setAction] = useState<string>("添加");
		const [form] = Form.useForm();
		const tmpArr = filterRoute(loadRouterArray())
		const [routeArr, setRouteArr] = useState<Role.RoleResDTO[]>(tmpArr);

		useImperativeHandle(ref, () => ({
			open: (id: string) => {
				let isEdit = false;
				setAction("添加");
				if (id) {
					isEdit = true;
					setAction("编辑");
				}
				setOpen(true);

				isEdit ? edit(id) : add();
			},
		}));

		// 新增
		const add = () => {
			form.resetFields()
			form.setFieldsValue({
				roleId: uuidv4(),
			});
		};

		function genRouteArr(arr: Role.RoleResDTO[], mm: Map<string, Role.RoleResDTO>) {
			arr.map((val) => {
				if (val.children && val.children.length > 0) {
					genRouteArr(val.children, mm)
				} else {
					let item = mm.get(val.resId)
					if (item) {
						val.read = true
						val.edit = item.edit
						val.fullControl = item.fullControl
						val.readIndeterminate = false
						val.editIndeterminate = item.editIndeterminate
						val.fullControlIndeterminate = item.fullControlIndeterminate
					}
				}
			})
		}
		const parentCheck = (rootArr: Role.RoleResDTO[], curArr: Role.RoleResDTO[]) => {
			curArr.map((val) => {
				if (val.children && val.children.length > 0) {
					parentCheck(rootArr, val.children)
					checkOneParent(val, RolePermission.read)
					checkOneParent(val, RolePermission.edit)
					checkOneParent(val, RolePermission.fullControl)
				}
			})
		}
		const edit = async (id: string) => {
			let res = await roleView(id);
			form.setFieldsValue(res.data);
			let mm = new Map()
			res?.data?.resArr?.map((val) => {
				mm.set(val.resId, val)
			})
			let arr = filterRoute(loadRouterArray())
			genRouteArr(arr, mm)
			parentCheck(arr, arr)
			setRouteArr(arr)

			console.log('arr', arr)
		};

		// 关闭抽屉
		const onClose = () => {
			setOpen(false);
		};

		//保存
		const onOK = async () => {
			let values = await form.validateFields();
			if (values) {
				let resArr = toSelectedArr(routeArr)
				form.setFieldValue('resArr', resArr)
				let param = form.getFieldsValue();

				let res = await roleSave(param);
				if (res.data && props.update) {
					props.update(res.data);
				}
				onClose();
			}
		};
		const checkOneParent = (item: Role.RoleResDTO, type: RolePermission) => {
			let total = item.children?.length
			let match = 0
			item?.children?.map((val: Role.RoleResDTO) => {
				if (val[type]) {
					match++
				}
			})
			if (total == match) {
				//全选 
				updateOneParentLine(item, type, true, false)
			} else if (match == 0) {
				//清空
				updateOneParentLine(item, type, false, false)
			} else {
				//半选
				updateOneParentLine(item, type, false, true)
			}
		}
		const updateOneParent = (arr: Role.RoleResDTO[], parentKey: string, type: RolePermission) => {
			let find = false
			let nextArr: Role.RoleResDTO[][] = []
			for (let i = 0; i < arr?.length; i++) {
				let item = arr[i]
				if (item.resId === parentKey) {
					console.log('updateOneParent', item)
					find = true
					checkOneParent(item, type)
					break;
				}
				if (item.children && item.children.length > 0) {
					nextArr.push(item.children)
				}
			}
			if (!find) {
				nextArr.map((val) => {
					updateOneParent(val, parentKey, type)
				})
			}
		}
		const updateParent = (rootArr: Role.RoleResDTO[], key: string) => {
			let curKey = key
			let map = genParentMap(rootArr, 'resId')
			// 检查所有的父节点
			for (let i = 0; i < 100; i++) {
				let parentKey = map.get(curKey)
				if (!parentKey) {
					break
				}
				updateOneParent(rootArr, parentKey, RolePermission.read)
				updateOneParent(rootArr, parentKey, RolePermission.edit)
				updateOneParent(rootArr, parentKey, RolePermission.fullControl)
				curKey = parentKey
			}
		}
		const updateChildren = (arr: Role.RoleResDTO[], type: RolePermission, checked: boolean) => {
			if (!arr) {
				return
			}
			arr.map((val) => {
				updateOneLine(val, type, checked)
				if (val.children) {
					updateChildren(val.children, type, checked)
				}
			})
		}
		const onCheckChange = (record: Role.RoleResDTO, type: RolePermission, checked: boolean) => {
			updateOneLine(record, type, checked)
			updateParent(routeArr, record.resId)
			if (record.children) {
				updateChildren(record.children, type, checked)
			}

			setRouteArr([...routeArr])
		};


		/**
		 * 行内联动修改
		 * 
		 * @param record 一行记录
		 * @param type 类型
		 * @param checked 是否选中
		 */
		const updateOneLine = (record: Role.RoleResDTO, type: RolePermission, checked: boolean) => {
			record[type] = checked
			if (checked) {
				if (RolePermission.edit == type) {
					record.read = checked
					record.readIndeterminate = false
				} else if (RolePermission.fullControl == type) {
					record.read = checked
					record.readIndeterminate = false
					record.edit = checked
					record.editIndeterminate = false
				}
			} else {
				if (RolePermission.edit == type) {
					record.fullControl = checked
				} else if (RolePermission.read == type) {
					record.fullControl = checked
					record.edit = checked
				}
			}
			console.log('updateOneLine', record)
		}

		/**
		 * 行内联动修改,用于修改父节点
		 * 
		 * @param record 一行记录
		 * @param type 类型
		 * @param checked 是否选中
		 */
		const updateOneParentLine = (record: Role.RoleResDTO, type: RolePermission, checked: boolean, indeterminate: boolean = false) => {
			record[type] = checked

			if (RolePermission.read == type) {
				record.readIndeterminate = indeterminate
			} else if (RolePermission.edit == type) {
				record.editIndeterminate = indeterminate
			} else if (RolePermission.fullControl == type) {
				record.fullControlIndeterminate = indeterminate
			}
		}

		const columns: any[] = [
			{
				title: "菜单",
				dataIndex: "title",
				key: "title",
				align: "left",
			},
			{
				title: "查看",
				dataIndex: "read",
				key: "read",
				width: 60,
				align: "center",
				render: (val: string, record: Role.RoleResDTO) => (
					<Checkbox indeterminate={record.readIndeterminate} onChange={(e) => onCheckChange(record, RolePermission.read, e.target.checked)} checked={record.read}></Checkbox>
				),
			},
			{
				title: "编辑",
				dataIndex: "write",
				key: "write",
				width: 60,
				align: "center",
				render: (val: string, record: Role.RoleResDTO) => (
					<Checkbox indeterminate={record.editIndeterminate} onChange={(e) => onCheckChange(record, RolePermission.edit, e.target.checked)} checked={record.edit}></Checkbox>
				),
			},
			{
				title: "完全控制",
				dataIndex: "full",
				key: "full",
				width: 100,
				align: "center",
				render: (val: string, record: Role.RoleResDTO) => (
					<Checkbox indeterminate={record.fullControlIndeterminate} onChange={(e) => onCheckChange(record, RolePermission.fullControl, e.target.checked)} checked={record.fullControl}></Checkbox>
				),
			},
		];

		return (
			<Drawer
				title={action + "角色"}
				width={720}
				onClose={onClose}
				open={open}
				styles={{
					body: {
						paddingBottom: 80,
					},
				}}
				extra={
					<Space>
						<Button onClick={onClose}>取消</Button>
						<Button onClick={onOK} type="primary">
							提交
						</Button>
					</Space>
				}
			>
				<Form form={form} labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
					<Form.Item hidden name="roleId" />
					<Form.Item hidden name="resArr" />
					<Form.Item name="roleName" label="角色名称" rules={[{ required: true, message: "请输入角色名称" }]}>
						<Input placeholder="请输入角色名称" />
					</Form.Item>
					<Form.Item name="note" label="备注">
						<Input placeholder="请输入备注" />
					</Form.Item>
					<Table rowKey={'resId'} pagination={false} columns={columns} dataSource={routeArr}></Table>
				</Form>
			</Drawer>
		);
	})
);
function filterRoute(arr?: RouteObject[]): Role.RoleResDTO[] {
	let res: Role.RoleResDTO[] = [];
	if (!arr) {
		return res
	}
	arr.map((val) => {
		if (val.skipAuth) {
			return;
		}
		res.push({
			resId: val.key,
			title: val.title,
			children: val.children ? filterRoute(val.children) : undefined
		});
	});
	return res;
}

function toSelectedArr(arr: Role.RoleResDTO[]): Role.RoleResDTO[] {
	let newArr: Role.RoleResDTO[] = []
	arr.forEach((item: Role.RoleResDTO) => {
		if (item.read || item.readIndeterminate) {
			newArr.push({ ...item, children: undefined })
		}
		if (item.children && item.children.length > 0) {
			newArr.push(...toSelectedArr(item.children))
		}
	});
	return newArr;
}